参考:
为什么用Object.prototype.toString.call(obj)检测对象类型
为什么用Object.prototype.toString.call()判断数据类型?
typeof
不能正确判断数据类型:
1 | var a = null |
使用Object.prototype.toString.call(obj)
可以准确判断各种类型(无法判断自定义对象类型,用instanceof判断自定义类型):
1 | Object.prototype.toString.call('hello world') |
为什么不直接用obj.toString()
?
1 | "hello world".toString() |
因为toString
是Object
的原型方法,Array
、Function
等类型作为Object
的实例,都重写了toString
方法。不同的数据类型调用toString
方法时,根据原型链的知识,调用的是重写之后的toString
方法。因此,想要得到对象的具体类型,应调用Object
上原型toString
方法。
将数组的toString
方法删除,看看会是什么结果:
1 | var arr = [1, 2, 3] |
删除了Array
的toString
方法后,再调用arr.toString()
方法时,不再有屏蔽Object
原型方法的实例方法,因此arr沿着原型链最后调用了Object
的toString
方法,返回了和Object.prototype.toString.call(arr)
相同的结果。
ECMAScript 5 Object.prototype.toString() 规范
在ECMAScript 5中,Object.prototype.toString()
被调用时,会进行如下步骤:
如果
this
的值是undefined
,返回[object Undefined]
如果
this
的值是null
,返回[object Null]
让
O
成为调用ToObject(this)
的结果让
class
成为O
的内部属性[[Class]]
的值返回三个字符串
"[object"
,class
, 以及"]"
拼接而成的字符串
[[Class]]
是一个内部属性,值为一个类型字符串,表明了该对象的类型。
本规范的每种内置对象都定义了 [[Class]] 内部属性的值。宿主对象的 [[Class]] 内部属性的值可以是除了 “Arguments”、”Array”、”Boolean”、”Date”、”Error”、”Function”、”JSON”、”Math”、”Number”、”Object”、”RegExp”、”String” 的任何字符串。(出自ES5/类型)
在JavaScript代码里,唯一可以访问[[Class]]
属性的方法就是通过Object.prototype.toString
。可以用下列函数,来获取任意变量的[[Class]]
属性:
1 | function getClass (a) { |